@dxos/react-ui-editor 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/lib/browser/index.mjs +1110 -1127
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +1133 -1164
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +1110 -1127
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -0
  12. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
  13. package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
  14. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
  15. package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
  16. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
  17. package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
  18. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
  19. package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
  20. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
  21. package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
  22. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
  23. package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
  24. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  25. package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
  26. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
  28. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
  29. package/dist/types/src/components/index.d.ts +1 -1
  30. package/dist/types/src/components/index.d.ts.map +1 -1
  31. package/dist/types/src/extensions/comments.d.ts +3 -4
  32. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  33. package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
  34. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
  35. package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
  36. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  37. package/dist/types/src/extensions/markdown/index.d.ts +1 -1
  38. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  40. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  41. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  42. package/dist/types/src/index.d.ts +1 -0
  43. package/dist/types/src/index.d.ts.map +1 -1
  44. package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
  45. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
  46. package/dist/types/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +30 -29
  48. package/src/InputMode.stories.tsx +7 -10
  49. package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
  50. package/src/components/EditorToolbar/blocks.ts +41 -0
  51. package/src/components/EditorToolbar/comment.ts +23 -0
  52. package/src/components/EditorToolbar/formatting.ts +41 -0
  53. package/src/components/EditorToolbar/headings.ts +59 -0
  54. package/src/components/EditorToolbar/index.ts +6 -0
  55. package/src/components/EditorToolbar/lists.ts +40 -0
  56. package/src/components/EditorToolbar/util.ts +65 -0
  57. package/src/components/EditorToolbar/viewMode.ts +48 -0
  58. package/src/components/index.ts +1 -1
  59. package/src/extensions/comments.ts +8 -15
  60. package/src/extensions/markdown/decorate.ts +1 -1
  61. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  62. package/src/extensions/markdown/formatting.test.ts +7 -6
  63. package/src/extensions/markdown/formatting.ts +20 -24
  64. package/src/extensions/markdown/index.ts +1 -1
  65. package/src/extensions/markdown/styles.ts +21 -0
  66. package/src/hooks/useActionHandler.ts +4 -4
  67. package/src/index.ts +4 -0
  68. package/src/styles/markdown.ts +1 -1
  69. package/src/styles/stack-item-content-class-names.ts +17 -0
  70. package/src/styles/theme.ts +1 -1
  71. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  72. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  73. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  74. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  75. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  76. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  77. package/src/components/Toolbar/Toolbar.tsx +0 -522
  78. package/src/components/Toolbar/index.ts +0 -5
@@ -39,258 +39,860 @@ import { EditorView as EditorView21, keymap as keymap11 } from "@codemirror/view
39
39
  import { tags as tags2 } from "@lezer/highlight";
40
40
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
41
41
 
42
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
43
- import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
44
- import { createContext } from "@radix-ui/react-context";
45
- import React3, { useEffect as useEffect2, useRef, useState as useState3 } from "react";
46
- import { useDropzone } from "react-dropzone";
47
- import { Button, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
48
- import { getSize } from "@dxos/react-ui-theme";
42
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
43
+ import React, { useCallback } from "react";
44
+ import { ElevationProvider } from "@dxos/react-ui";
45
+ import { ToolbarMenu, MenuProvider, useMenuActions, createGapSeparator } from "@dxos/react-ui-menu";
46
+ import { textBlockWidth } from "@dxos/react-ui-theme";
49
47
 
50
- // packages/ui/react-ui-editor/src/extensions/annotations.ts
51
- import { StateField } from "@codemirror/state";
52
- import { Decoration, EditorView } from "@codemirror/view";
53
- import { isNotFalsy } from "@dxos/util";
54
-
55
- // packages/ui/react-ui-editor/src/util/facet.ts
56
- import { Facet } from "@codemirror/state";
57
- var singleValueFacet = (defaultValue) => Facet.define({
58
- // Called immediately.
59
- combine: (providers) => {
60
- return providers[0] ?? defaultValue;
48
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
49
+ import { useMemo } from "react";
50
+ import { create } from "@dxos/live-object";
51
+ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
52
+ var useEditorToolbarState = (initialState = {}) => {
53
+ return useMemo(() => create(initialState), []);
54
+ };
55
+ var createEditorAction = (payload, icon, label = [
56
+ `${payload.type} label`,
57
+ {
58
+ ns: translationKey
61
59
  }
60
+ ], id = payload.type) => createMenuAction(id, {
61
+ icon,
62
+ label,
63
+ ...payload
64
+ });
65
+ var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
66
+ icon,
67
+ iconOnly: true,
68
+ ...props
62
69
  });
70
+ var editorToolbarSearch = createEditorAction({
71
+ type: "search"
72
+ }, "ph--magnifying-glass--regular");
63
73
 
64
- // packages/ui/react-ui-editor/src/util/cursor.ts
65
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
66
- var defaultCursorConverter = {
67
- toCursor: (position) => position.toString(),
68
- fromCursor: (cursor) => parseInt(cursor)
69
- };
70
- var Cursor = class _Cursor {
71
- static {
72
- this.converter = singleValueFacet(defaultCursorConverter);
73
- }
74
- static {
75
- this.getCursorFromRange = (state, range) => {
76
- const cursorConverter2 = state.facet(_Cursor.converter);
77
- const from = cursorConverter2.toCursor(range.from);
78
- const to = cursorConverter2.toCursor(range.to, -1);
79
- return [
80
- from,
81
- to
82
- ].join(":");
83
- };
84
- }
85
- static {
86
- this.getRangeFromCursor = (state, cursor) => {
87
- const cursorConverter2 = state.facet(_Cursor.converter);
88
- const parts = cursor.split(":");
89
- const from = cursorConverter2.fromCursor(parts[0]);
90
- const to = cursorConverter2.fromCursor(parts[1]);
91
- return from !== void 0 && to !== void 0 ? {
92
- from,
93
- to
94
- } : void 0;
95
- };
96
- }
74
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
75
+ var createBlockGroupAction = (value) => createEditorActionGroup("block", {
76
+ variant: "toggleGroup",
77
+ selectCardinality: "single",
78
+ value
79
+ });
80
+ var createBlockActions = (value, blankLine) => Object.entries({
81
+ blockquote: "ph--quotes--regular",
82
+ codeblock: "ph--code-block--regular",
83
+ table: "ph--table--regular"
84
+ }).map(([type, icon]) => {
85
+ return createEditorAction({
86
+ type,
87
+ checked: type === value,
88
+ ...type === "table" && {
89
+ disabled: !!blankLine
90
+ }
91
+ }, icon);
92
+ });
93
+ var createBlocks = (state) => {
94
+ const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
95
+ const blockGroupAction = createBlockGroupAction(value);
96
+ const blockActions = createBlockActions(value, state.blankLine);
97
+ return {
98
+ nodes: [
99
+ blockGroupAction,
100
+ ...blockActions
101
+ ],
102
+ edges: [
103
+ {
104
+ source: "root",
105
+ target: "block"
106
+ },
107
+ ...blockActions.map(({ id }) => ({
108
+ source: blockGroupAction.id,
109
+ target: id
110
+ }))
111
+ ]
112
+ };
97
113
  };
98
114
 
99
- // packages/ui/react-ui-editor/src/util/debug.ts
100
- import { log } from "@dxos/log";
101
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
102
- var wrapWithCatch = (fn) => {
103
- return (...args) => {
104
- try {
105
- return fn(...args);
106
- } catch (err) {
107
- log.catch(err, void 0, {
108
- F: __dxlog_file,
109
- L: 15,
110
- S: void 0,
111
- C: (f, a) => f(...a)
112
- });
115
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
116
+ var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
117
+ var createCommentAction = (label) => createEditorAction({
118
+ type: "comment",
119
+ testId: "editor.toolbar.comment"
120
+ }, "ph--chat-text--regular", label);
121
+ var createComment = (state) => ({
122
+ nodes: [
123
+ createCommentAction([
124
+ commentLabel(state.comment, state.selection),
125
+ {
126
+ ns: translationKey
127
+ }
128
+ ])
129
+ ],
130
+ edges: [
131
+ {
132
+ source: "root",
133
+ target: "comment"
113
134
  }
135
+ ]
136
+ });
137
+
138
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
139
+ var formats = {
140
+ strong: "ph--text-b--regular",
141
+ emphasis: "ph--text-italic--regular",
142
+ strikethrough: "ph--text-strikethrough--regular",
143
+ code: "ph--code--regular",
144
+ link: "ph--link--regular"
145
+ };
146
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
147
+ variant: "toggleGroup",
148
+ selectCardinality: "multiple",
149
+ value: Object.keys(formats).filter((key) => !!formatting[key])
150
+ });
151
+ var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
152
+ type,
153
+ checked: !!formatting[type]
154
+ }, icon));
155
+ var createFormatting = (state) => {
156
+ const formattingGroupAction = createFormattingGroup(state);
157
+ const formattingActions = createFormattingActions(state);
158
+ return {
159
+ nodes: [
160
+ formattingGroupAction,
161
+ ...formattingActions
162
+ ],
163
+ edges: [
164
+ {
165
+ source: "root",
166
+ target: "formatting"
167
+ },
168
+ ...formattingActions.map(({ id }) => ({
169
+ source: formattingGroupAction.id,
170
+ target: id
171
+ }))
172
+ ]
114
173
  };
115
174
  };
116
- var callbackWrapper = (fn) => (...args) => {
117
- try {
118
- return fn(...args);
119
- } catch (err) {
120
- log.catch(err, void 0, {
121
- F: __dxlog_file,
122
- L: 29,
123
- S: void 0,
124
- C: (f, a) => f(...a)
125
- });
126
- }
175
+
176
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
177
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
178
+ variant: "dropdownMenu",
179
+ applyActive: true,
180
+ selectCardinality: "single",
181
+ value
182
+ }, "ph--text-h--regular");
183
+ var createHeadingActions = (value) => Object.entries({
184
+ "0": "ph--paragraph--regular",
185
+ "1": "ph--text-h-one--regular",
186
+ "2": "ph--text-h-two--regular",
187
+ "3": "ph--text-h-three--regular",
188
+ "4": "ph--text-h-four--regular",
189
+ "5": "ph--text-h-five--regular",
190
+ "6": "ph--text-h-six--regular"
191
+ }).map(([levelStr, icon]) => {
192
+ const level = parseInt(levelStr);
193
+ return createEditorAction({
194
+ type: "heading",
195
+ data: level,
196
+ checked: value === levelStr
197
+ }, icon, [
198
+ "heading level label",
199
+ {
200
+ count: level,
201
+ ns: translationKey
202
+ }
203
+ ], `heading--${levelStr}`);
204
+ });
205
+ var computeHeadingValue = (state) => {
206
+ const blockType = state ? state.blockType : "paragraph";
207
+ const header = blockType && /heading(\d)/.exec(blockType);
208
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
127
209
  };
128
- var debugDispatcher = (trs, view) => {
129
- logChanges(trs);
130
- view.update(trs);
210
+ var createHeadings = (state) => {
211
+ const headingValue = computeHeadingValue(state);
212
+ const headingGroupAction = createHeadingGroupAction(headingValue);
213
+ const headingActions = createHeadingActions(headingValue);
214
+ return {
215
+ nodes: [
216
+ headingGroupAction,
217
+ ...headingActions
218
+ ],
219
+ edges: [
220
+ {
221
+ source: "root",
222
+ target: "heading"
223
+ },
224
+ ...headingActions.map(({ id }) => ({
225
+ source: headingGroupAction.id,
226
+ target: id
227
+ }))
228
+ ]
229
+ };
131
230
  };
132
- var logChanges = (trs) => {
133
- const changes = trs.flatMap((tr) => {
134
- if (tr.changes.empty) {
135
- return void 0;
231
+
232
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
233
+ var listStyles = {
234
+ bullet: "ph--list-bullets--regular",
235
+ ordered: "ph--list-numbers--regular",
236
+ task: "ph--list-checks--regular"
237
+ };
238
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
239
+ variant: "toggleGroup",
240
+ selectCardinality: "single",
241
+ value
242
+ });
243
+ var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
244
+ type: `list-${listStyle}`,
245
+ checked: value === listStyle
246
+ }, icon));
247
+ var createLists = (state) => {
248
+ const value = state.listStyle ?? "";
249
+ const listGroupAction = createListGroupAction(value);
250
+ const listActionsMap = createListActions(value);
251
+ return {
252
+ nodes: [
253
+ listGroupAction,
254
+ ...listActionsMap
255
+ ],
256
+ edges: [
257
+ {
258
+ source: "root",
259
+ target: "list"
260
+ },
261
+ ...listActionsMap.map(({ id }) => ({
262
+ source: listGroupAction.id,
263
+ target: id
264
+ }))
265
+ ]
266
+ };
267
+ };
268
+
269
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
270
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
271
+ variant: "dropdownMenu",
272
+ applyActive: true,
273
+ selectCardinality: "single",
274
+ value
275
+ }, "ph--eye--regular");
276
+ var createViewModeActions = (value) => Object.entries({
277
+ preview: "ph--eye--regular",
278
+ source: "ph--pencil-simple--regular",
279
+ readonly: "ph--pencil-slash--regular"
280
+ }).map(([viewMode, icon]) => {
281
+ return createEditorAction({
282
+ type: "view-mode",
283
+ data: viewMode,
284
+ checked: viewMode === value
285
+ }, icon, [
286
+ `${viewMode} mode label`,
287
+ {
288
+ ns: translationKey
136
289
  }
137
- const changes2 = [];
138
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
139
- fromA,
140
- toA,
141
- fromB,
142
- toB,
143
- inserted: inserted.toString()
144
- })));
145
- return changes2;
146
- }).filter(Boolean);
147
- if (changes.length) {
148
- log.info("changes", {
149
- changes
150
- }, {
151
- F: __dxlog_file,
152
- L: 62,
153
- S: void 0,
154
- C: (f, a) => f(...a)
155
- });
156
- }
290
+ ], `view-mode--${viewMode}`);
291
+ });
292
+ var createViewMode = (state) => {
293
+ const value = state.viewMode ?? "source";
294
+ const viewModeGroupAction = createViewModeGroupAction(value);
295
+ const viewModeActions = createViewModeActions(value);
296
+ return {
297
+ nodes: [
298
+ viewModeGroupAction,
299
+ ...viewModeActions
300
+ ],
301
+ edges: [
302
+ {
303
+ source: "root",
304
+ target: "viewMode"
305
+ },
306
+ ...viewModeActions.map(({ id }) => ({
307
+ source: viewModeGroupAction.id,
308
+ target: id
309
+ }))
310
+ ]
311
+ };
157
312
  };
158
313
 
159
- // packages/ui/react-ui-editor/src/util/dom.ts
160
- var flattenRect = (rect, left) => {
161
- const x = left ? rect.left : rect.right;
314
+ // packages/ui/react-ui-editor/src/styles/stack-item-content-class-names.ts
315
+ import { mx } from "@dxos/react-ui-theme";
316
+ var stackItemContentEditorClassNames = (role) => mx("dx-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
317
+ var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
318
+
319
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
320
+ var createToolbar = ({ state, customActions, ...features }) => {
321
+ const nodes = [];
322
+ const edges = [];
323
+ if (features.headings ?? true) {
324
+ const headings2 = createHeadings(state);
325
+ nodes.push(...headings2.nodes);
326
+ edges.push(...headings2.edges);
327
+ }
328
+ if (features.formatting ?? true) {
329
+ const formatting = createFormatting(state);
330
+ nodes.push(...formatting.nodes);
331
+ edges.push(...formatting.edges);
332
+ }
333
+ if (features.lists ?? true) {
334
+ const lists = createLists(state);
335
+ nodes.push(...lists.nodes);
336
+ edges.push(...lists.edges);
337
+ }
338
+ if (features.blocks ?? true) {
339
+ const blocks = createBlocks(state);
340
+ nodes.push(...blocks.nodes);
341
+ edges.push(...blocks.edges);
342
+ }
343
+ if (customActions) {
344
+ const custom = customActions();
345
+ nodes.push(...custom.nodes);
346
+ edges.push(...custom.edges);
347
+ }
348
+ const editorToolbarGap = createGapSeparator();
349
+ nodes.push(...editorToolbarGap.nodes);
350
+ edges.push(...editorToolbarGap.edges);
351
+ if (features.comment ?? true) {
352
+ const comment = createComment(state);
353
+ nodes.push(...comment.nodes);
354
+ edges.push(...comment.edges);
355
+ }
356
+ if (features.search ?? true) {
357
+ nodes.push(editorToolbarSearch);
358
+ edges.push({
359
+ source: "root",
360
+ target: editorToolbarSearch.id
361
+ });
362
+ }
363
+ if (features.viewMode ?? true) {
364
+ const viewMode = createViewMode(state);
365
+ nodes.push(...viewMode.nodes);
366
+ edges.push(...viewMode.edges);
367
+ }
162
368
  return {
163
- left: x,
164
- right: x,
165
- top: rect.top,
166
- bottom: rect.bottom
369
+ nodes,
370
+ edges
167
371
  };
168
372
  };
169
- var scratchRange;
170
- var textRange = (node, from, to = from) => {
171
- const range = scratchRange || (scratchRange = document.createRange());
172
- range.setEnd(node, to);
173
- range.setStart(node, from);
174
- return range;
373
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
374
+ const menuCreator = useCallback(() => createToolbar(props), [
375
+ props
376
+ ]);
377
+ const { resolveGroupItems } = useMenuActions(menuCreator);
378
+ return {
379
+ resolveGroupItems,
380
+ onAction
381
+ };
175
382
  };
176
- var clientRectsFor = (dom) => {
177
- if (dom.nodeType === 3) {
178
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
179
- } else if (dom.nodeType === 1) {
180
- return dom.getClientRects();
181
- } else {
182
- return [];
183
- }
383
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
384
+ const menuProps = useEditorToolbarActionGraph(props);
385
+ return /* @__PURE__ */ React.createElement("div", {
386
+ role: "none",
387
+ className: stackItemContentToolbarClassNames(role)
388
+ }, /* @__PURE__ */ React.createElement(ElevationProvider, {
389
+ elevation: role === "section" ? "positioned" : "base"
390
+ }, /* @__PURE__ */ React.createElement(MenuProvider, {
391
+ ...menuProps,
392
+ attendableId
393
+ }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
394
+ classNames: [
395
+ textBlockWidth,
396
+ "!bg-transparent",
397
+ classNames
398
+ ]
399
+ }))));
184
400
  };
185
401
 
186
- // packages/ui/react-ui-editor/src/util/react.tsx
187
- import React from "react";
188
- import { createRoot } from "react-dom/client";
189
- import { ThemeProvider } from "@dxos/react-ui";
190
- import { defaultTx } from "@dxos/react-ui-theme";
191
- var createElement = (tag, options, children) => {
192
- const el = document.createElement(tag);
193
- if (options?.className) {
194
- el.className = options.className;
195
- }
196
- if (children) {
197
- el.append(...Array.isArray(children) ? children : [
198
- children
199
- ]);
402
+ // packages/ui/react-ui-editor/src/defaults.ts
403
+ import { EditorView } from "@codemirror/view";
404
+ import { mx as mx3 } from "@dxos/react-ui-theme";
405
+
406
+ // packages/ui/react-ui-editor/src/styles/markdown.ts
407
+ import { mx as mx2 } from "@dxos/react-ui-theme";
408
+ var headings = {
409
+ 1: "text-4xl",
410
+ 2: "text-3xl",
411
+ 3: "text-2xl",
412
+ 4: "text-xl",
413
+ 5: "text-lg",
414
+ 6: ""
415
+ };
416
+ var theme = {
417
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
418
+ codeMark: "font-mono text-primary-500",
419
+ mark: "opacity-50",
420
+ heading: (level) => {
421
+ return mx2(headings[level], "dark:text-primary-400");
200
422
  }
201
- return el;
202
423
  };
203
- var renderRoot = (root, node) => {
204
- createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
205
- tx: defaultTx
206
- }, node));
207
- return root;
424
+
425
+ // packages/ui/react-ui-editor/src/styles/tokens.ts
426
+ import get from "lodash.get";
427
+ import { tokens } from "@dxos/react-ui-theme";
428
+ var getToken = (path, defaultValue) => {
429
+ const value = get(tokens, path, defaultValue);
430
+ return value?.toString() ?? "";
208
431
  };
432
+ var fontBody = getToken("fontFamily.body");
433
+ var fontMono = getToken("fontFamily.mono");
209
434
 
210
- // packages/ui/react-ui-editor/src/extensions/annotations.ts
211
- var annotationMark = Decoration.mark({
212
- class: "cm-annotation"
213
- });
214
- var annotations = (options = {}) => {
215
- const match = (state) => {
216
- const annotations2 = [];
217
- const text = state.doc.toString();
218
- if (options.match) {
219
- const matches = text.matchAll(options.match);
220
- for (const match2 of matches) {
221
- const from = match2.index;
222
- const to = from + match2[0].length;
223
- const cursor = Cursor.getCursorFromRange(state, {
224
- from,
225
- to
226
- });
227
- annotations2.push({
228
- cursor
229
- });
230
- }
231
- }
232
- return annotations2;
233
- };
234
- const annotationsState = StateField.define({
235
- create: (state) => {
236
- return match(state);
237
- },
238
- update: (value, tr) => {
239
- if (!tr.changes.empty) {
240
- return match(tr.state);
241
- }
242
- return value;
435
+ // packages/ui/react-ui-editor/src/styles/theme.ts
436
+ var defaultTheme = {
437
+ "&": {},
438
+ "&.cm-focused": {
439
+ outline: "none"
440
+ },
441
+ /**
442
+ * Scroller
443
+ */
444
+ ".cm-scroller": {
445
+ overflowY: "auto"
446
+ },
447
+ /**
448
+ * Content
449
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
450
+ */
451
+ ".cm-content": {
452
+ padding: "unset",
453
+ fontFamily: fontBody,
454
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
455
+ fontSize: "16px",
456
+ lineHeight: 1.5,
457
+ color: "unset"
458
+ },
459
+ /**
460
+ * Gutters
461
+ * NOTE: Gutters should have the same top margin as the content.
462
+ * NOTE: They can't be transparent since the content needs to scroll below.
463
+ */
464
+ ".cm-gutters": {
465
+ background: "var(--surface-bg)",
466
+ borderRight: "none"
467
+ },
468
+ ".cm-gutter": {},
469
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
470
+ minWidth: "40px",
471
+ alignContent: "center"
472
+ },
473
+ /**
474
+ * Height is set to match the corresponding line.
475
+ */
476
+ ".cm-gutterElement": {
477
+ alignItems: "center",
478
+ fontSize: "16px"
479
+ },
480
+ /**
481
+ * Line.
482
+ */
483
+ ".cm-line": {
484
+ paddingInline: 0
485
+ },
486
+ ".cm-activeLine": {
487
+ background: "var(--dx-cmActiveLine)"
488
+ },
489
+ /**
490
+ * Cursor (layer).
491
+ */
492
+ ".cm-cursor, .cm-dropCursor": {
493
+ borderLeft: "2px solid var(--dx-cmCursor)"
494
+ },
495
+ ".cm-placeholder": {
496
+ color: "var(--dx-subdued)"
497
+ },
498
+ /**
499
+ * Selection (layer).
500
+ */
501
+ ".cm-selectionBackground": {
502
+ background: "var(--dx-cmSelection)"
503
+ },
504
+ /**
505
+ * Search.
506
+ * NOTE: Matches comment.
507
+ */
508
+ ".cm-searchMatch": {
509
+ margin: "0 -3px",
510
+ padding: "3px",
511
+ borderRadius: "3px",
512
+ background: "var(--dx-cmHighlightSurface)",
513
+ color: "var(--dx-cmHighlight)"
514
+ },
515
+ ".cm-searchMatch-selected": {
516
+ textDecoration: "underline"
517
+ },
518
+ /**
519
+ * Link.
520
+ */
521
+ ".cm-link": {
522
+ textDecorationLine: "underline",
523
+ textDecorationThickness: "1px",
524
+ textUnderlineOffset: "2px",
525
+ borderRadius: ".125rem"
526
+ },
527
+ ".cm-link > span": {
528
+ color: "var(--dx-accentText)"
529
+ },
530
+ /**
531
+ * Tooltip.
532
+ */
533
+ ".cm-tooltip": {
534
+ background: "var(--dx-baseSurface)"
535
+ },
536
+ ".cm-tooltip-below": {},
537
+ /**
538
+ * Autocomplete.
539
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
540
+ */
541
+ ".cm-tooltip.cm-tooltip-autocomplete": {
542
+ marginTop: "4px",
543
+ marginLeft: "-3px"
544
+ },
545
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
546
+ maxHeight: "20em"
547
+ },
548
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
549
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
550
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
551
+ paddingLeft: "4px !important",
552
+ borderBottom: "none !important",
553
+ color: "var(--dx-accentText)"
554
+ },
555
+ ".cm-tooltip.cm-completionInfo": {
556
+ width: "360px !important",
557
+ margin: "-10px 1px 0 1px",
558
+ padding: "8px !important",
559
+ borderColor: "var(--dx-separator)"
560
+ },
561
+ ".cm-completionIcon": {
562
+ display: "none"
563
+ },
564
+ ".cm-completionLabel": {
565
+ fontFamily: fontBody
566
+ },
567
+ ".cm-completionMatchedText": {
568
+ textDecoration: "none !important",
569
+ opacity: 0.5
570
+ },
571
+ /**
572
+ * Panels
573
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
574
+ *
575
+ * Find/replace panel.
576
+ * <div class="cm-announced">...</div>
577
+ * <div class="cm-scroller">...</div>
578
+ * <div class="cm-panels cm-panels-bottom">
579
+ * <div class="cm-search cm-panel">
580
+ * <input class="cm-textfield" />
581
+ * <button class="cm-button">...</button>
582
+ * <label><input type="checkbox" />...</label>
583
+ * </div>
584
+ * </div
585
+ */
586
+ // TODO(burdon): Implement custom panel (with icon buttons).
587
+ ".cm-panels": {},
588
+ ".cm-panel": {
589
+ fontFamily: fontBody,
590
+ backgroundColor: "var(--surface-bg)"
591
+ },
592
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
593
+ color: "var(--dx-subdued)",
594
+ fontFamily: fontBody,
595
+ fontSize: "14px",
596
+ all: "unset",
597
+ margin: "3px !important",
598
+ padding: "2px 6px !important",
599
+ outline: "1px solid transparent"
600
+ },
601
+ ".cm-panel input, .cm-panel button": {
602
+ backgroundColor: "var(--dx-input)"
603
+ },
604
+ ".cm-panel input:focus, .cm-panel button:focus": {
605
+ outline: "1px solid var(--dx-accentFocusIndicator)"
606
+ },
607
+ ".cm-panel label": {
608
+ display: "inline-flex",
609
+ alignItems: "center",
610
+ cursor: "pointer"
611
+ },
612
+ ".cm-panel input.cm-textfield": {},
613
+ ".cm-panel input[type=checkbox]": {
614
+ width: "8px",
615
+ height: "8px",
616
+ marginRight: "6px !important",
617
+ padding: "2px !important",
618
+ color: "var(--dx-accentFocusIndicator)"
619
+ },
620
+ ".cm-panel button": {
621
+ "&:hover": {
622
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
623
+ },
624
+ "&:active": {
625
+ backgroundColor: "var(--dx-accentSurfaceHover)"
243
626
  }
244
- });
245
- return [
246
- annotationsState,
247
- EditorView.decorations.compute([
248
- annotationsState
249
- ], (state) => {
250
- const annotations2 = state.field(annotationsState);
251
- const decorations = annotations2.map((annotation) => {
252
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
253
- return range && annotationMark.range(range.from, range.to);
254
- }).filter(isNotFalsy);
255
- return Decoration.set(decorations);
256
- }),
257
- styles
258
- ];
627
+ },
628
+ ".cm-panel.cm-search": {
629
+ padding: "4px",
630
+ borderTop: "1px solid var(--dx-separator)"
631
+ }
259
632
  };
260
- var styles = EditorView.theme({
261
- ".cm-annotation": {
262
- textDecoration: "underline",
263
- textDecorationStyle: "wavy",
264
- textDecorationColor: "var(--dx-error)"
633
+
634
+ // packages/ui/react-ui-editor/src/defaults.ts
635
+ var margin = "!mt-[1rem]";
636
+ var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
637
+ var editorFullWidth = mx3(margin);
638
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
639
+ var editorGutter = EditorView.theme({
640
+ // Match margin from content.
641
+ ".cm-gutters": {
642
+ marginTop: "16px",
643
+ paddingRight: "1rem"
644
+ }
645
+ });
646
+ var editorMonospace = EditorView.theme({
647
+ ".cm-content": {
648
+ fontFamily: fontMono
265
649
  }
266
650
  });
267
651
 
268
- // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
269
- import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
270
- import { markdownLanguage } from "@codemirror/lang-markdown";
271
- import { keymap } from "@codemirror/view";
272
- var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
273
- const extensions = [
274
- // https://codemirror.net/docs/ref/#view.keymap
275
- // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
276
- // TODO(burdon): Set custom keymap.
277
- keymap.of(completionKeymap),
278
- // https://codemirror.net/examples/autocompletion
279
- // https://codemirror.net/docs/ref/#autocomplete.autocompletion
280
- autocompletion({
281
- activateOnTyping,
282
- override,
283
- closeOnBlur: !debug,
284
- tooltipClass: () => "shadow rounded"
285
- })
286
- ];
287
- if (onSearch) {
288
- extensions.push(
289
- // TODO(burdon): Optional decoration via addToOptions
290
- markdownLanguage.data.of({
291
- autocomplete: (context) => {
292
- const match = context.matchBefore(/\w*/);
293
- if (!match || match.from === match.to && !context.explicit) {
652
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
653
+ import { StateField } from "@codemirror/state";
654
+ import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
655
+ import { isNotFalsy } from "@dxos/util";
656
+
657
+ // packages/ui/react-ui-editor/src/util/facet.ts
658
+ import { Facet } from "@codemirror/state";
659
+ var singleValueFacet = (defaultValue) => Facet.define({
660
+ // Called immediately.
661
+ combine: (providers) => {
662
+ return providers[0] ?? defaultValue;
663
+ }
664
+ });
665
+
666
+ // packages/ui/react-ui-editor/src/util/cursor.ts
667
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
668
+ var defaultCursorConverter = {
669
+ toCursor: (position) => position.toString(),
670
+ fromCursor: (cursor) => parseInt(cursor)
671
+ };
672
+ var Cursor = class _Cursor {
673
+ static {
674
+ this.converter = singleValueFacet(defaultCursorConverter);
675
+ }
676
+ static {
677
+ this.getCursorFromRange = (state, range) => {
678
+ const cursorConverter2 = state.facet(_Cursor.converter);
679
+ const from = cursorConverter2.toCursor(range.from);
680
+ const to = cursorConverter2.toCursor(range.to, -1);
681
+ return [
682
+ from,
683
+ to
684
+ ].join(":");
685
+ };
686
+ }
687
+ static {
688
+ this.getRangeFromCursor = (state, cursor) => {
689
+ const cursorConverter2 = state.facet(_Cursor.converter);
690
+ const parts = cursor.split(":");
691
+ const from = cursorConverter2.fromCursor(parts[0]);
692
+ const to = cursorConverter2.fromCursor(parts[1]);
693
+ return from !== void 0 && to !== void 0 ? {
694
+ from,
695
+ to
696
+ } : void 0;
697
+ };
698
+ }
699
+ };
700
+
701
+ // packages/ui/react-ui-editor/src/util/debug.ts
702
+ import { log } from "@dxos/log";
703
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
704
+ var wrapWithCatch = (fn) => {
705
+ return (...args) => {
706
+ try {
707
+ return fn(...args);
708
+ } catch (err) {
709
+ log.catch(err, void 0, {
710
+ F: __dxlog_file,
711
+ L: 15,
712
+ S: void 0,
713
+ C: (f, a) => f(...a)
714
+ });
715
+ }
716
+ };
717
+ };
718
+ var callbackWrapper = (fn) => (...args) => {
719
+ try {
720
+ return fn(...args);
721
+ } catch (err) {
722
+ log.catch(err, void 0, {
723
+ F: __dxlog_file,
724
+ L: 29,
725
+ S: void 0,
726
+ C: (f, a) => f(...a)
727
+ });
728
+ }
729
+ };
730
+ var debugDispatcher = (trs, view) => {
731
+ logChanges(trs);
732
+ view.update(trs);
733
+ };
734
+ var logChanges = (trs) => {
735
+ const changes = trs.flatMap((tr) => {
736
+ if (tr.changes.empty) {
737
+ return void 0;
738
+ }
739
+ const changes2 = [];
740
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
741
+ fromA,
742
+ toA,
743
+ fromB,
744
+ toB,
745
+ inserted: inserted.toString()
746
+ })));
747
+ return changes2;
748
+ }).filter(Boolean);
749
+ if (changes.length) {
750
+ log.info("changes", {
751
+ changes
752
+ }, {
753
+ F: __dxlog_file,
754
+ L: 62,
755
+ S: void 0,
756
+ C: (f, a) => f(...a)
757
+ });
758
+ }
759
+ };
760
+
761
+ // packages/ui/react-ui-editor/src/util/dom.ts
762
+ var flattenRect = (rect, left) => {
763
+ const x = left ? rect.left : rect.right;
764
+ return {
765
+ left: x,
766
+ right: x,
767
+ top: rect.top,
768
+ bottom: rect.bottom
769
+ };
770
+ };
771
+ var scratchRange;
772
+ var textRange = (node, from, to = from) => {
773
+ const range = scratchRange || (scratchRange = document.createRange());
774
+ range.setEnd(node, to);
775
+ range.setStart(node, from);
776
+ return range;
777
+ };
778
+ var clientRectsFor = (dom) => {
779
+ if (dom.nodeType === 3) {
780
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
781
+ } else if (dom.nodeType === 1) {
782
+ return dom.getClientRects();
783
+ } else {
784
+ return [];
785
+ }
786
+ };
787
+
788
+ // packages/ui/react-ui-editor/src/util/react.tsx
789
+ import React2 from "react";
790
+ import { createRoot } from "react-dom/client";
791
+ import { ThemeProvider } from "@dxos/react-ui";
792
+ import { defaultTx } from "@dxos/react-ui-theme";
793
+ var createElement = (tag, options, children) => {
794
+ const el = document.createElement(tag);
795
+ if (options?.className) {
796
+ el.className = options.className;
797
+ }
798
+ if (children) {
799
+ el.append(...Array.isArray(children) ? children : [
800
+ children
801
+ ]);
802
+ }
803
+ return el;
804
+ };
805
+ var renderRoot = (root, node) => {
806
+ createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
807
+ tx: defaultTx
808
+ }, node));
809
+ return root;
810
+ };
811
+
812
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
813
+ var annotationMark = Decoration.mark({
814
+ class: "cm-annotation"
815
+ });
816
+ var annotations = (options = {}) => {
817
+ const match = (state) => {
818
+ const annotations2 = [];
819
+ const text = state.doc.toString();
820
+ if (options.match) {
821
+ const matches = text.matchAll(options.match);
822
+ for (const match2 of matches) {
823
+ const from = match2.index;
824
+ const to = from + match2[0].length;
825
+ const cursor = Cursor.getCursorFromRange(state, {
826
+ from,
827
+ to
828
+ });
829
+ annotations2.push({
830
+ cursor
831
+ });
832
+ }
833
+ }
834
+ return annotations2;
835
+ };
836
+ const annotationsState = StateField.define({
837
+ create: (state) => {
838
+ return match(state);
839
+ },
840
+ update: (value, tr) => {
841
+ if (!tr.changes.empty) {
842
+ return match(tr.state);
843
+ }
844
+ return value;
845
+ }
846
+ });
847
+ return [
848
+ annotationsState,
849
+ EditorView2.decorations.compute([
850
+ annotationsState
851
+ ], (state) => {
852
+ const annotations2 = state.field(annotationsState);
853
+ const decorations = annotations2.map((annotation) => {
854
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
855
+ return range && annotationMark.range(range.from, range.to);
856
+ }).filter(isNotFalsy);
857
+ return Decoration.set(decorations);
858
+ }),
859
+ styles
860
+ ];
861
+ };
862
+ var styles = EditorView2.theme({
863
+ ".cm-annotation": {
864
+ textDecoration: "underline",
865
+ textDecorationStyle: "wavy",
866
+ textDecorationColor: "var(--dx-error)"
867
+ }
868
+ });
869
+
870
+ // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
871
+ import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
872
+ import { markdownLanguage } from "@codemirror/lang-markdown";
873
+ import { keymap } from "@codemirror/view";
874
+ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
875
+ const extensions = [
876
+ // https://codemirror.net/docs/ref/#view.keymap
877
+ // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
878
+ // TODO(burdon): Set custom keymap.
879
+ keymap.of(completionKeymap),
880
+ // https://codemirror.net/examples/autocompletion
881
+ // https://codemirror.net/docs/ref/#autocomplete.autocompletion
882
+ autocompletion({
883
+ activateOnTyping,
884
+ override,
885
+ closeOnBlur: !debug,
886
+ tooltipClass: () => "shadow rounded"
887
+ })
888
+ ];
889
+ if (onSearch) {
890
+ extensions.push(
891
+ // TODO(burdon): Optional decoration via addToOptions
892
+ markdownLanguage.data.of({
893
+ autocomplete: (context) => {
894
+ const match = context.matchBefore(/\w*/);
895
+ if (!match || match.from === match.to && !context.explicit) {
294
896
  return null;
295
897
  }
296
898
  return {
@@ -306,7 +908,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
306
908
 
307
909
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
308
910
  import { StateField as StateField2 } from "@codemirror/state";
309
- import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
911
+ import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
310
912
  import { next as A3 } from "@dxos/automerge/automerge";
311
913
 
312
914
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
@@ -590,7 +1192,7 @@ var automerge = (accessor) => {
590
1192
  }
591
1193
  }),
592
1194
  // Reconcile local updates.
593
- EditorView2.updateListener.of(({ view, changes }) => {
1195
+ EditorView3.updateListener.of(({ view, changes }) => {
594
1196
  if (!changes.empty) {
595
1197
  syncer.reconcile(view, true);
596
1198
  }
@@ -600,7 +1202,7 @@ var automerge = (accessor) => {
600
1202
 
601
1203
  // packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
602
1204
  import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
603
- import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
1205
+ import { Decoration as Decoration2, EditorView as EditorView4, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
604
1206
  import { Event } from "@dxos/async";
605
1207
  import { Context } from "@dxos/context";
606
1208
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
@@ -774,7 +1376,7 @@ var RemoteCaretWidget = class extends WidgetType {
774
1376
  return true;
775
1377
  }
776
1378
  };
777
- var styles2 = EditorView3.theme({
1379
+ var styles2 = EditorView4.theme({
778
1380
  ".cm-collab-selection": {},
779
1381
  ".cm-collab-selectionLine": {
780
1382
  padding: 0,
@@ -940,7 +1542,7 @@ var SpaceAwarenessProvider = class {
940
1542
  };
941
1543
 
942
1544
  // packages/ui/react-ui-editor/src/extensions/blast.ts
943
- import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
1545
+ import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
944
1546
  import defaultsDeep from "lodash.defaultsdeep";
945
1547
  import { invariant as invariant2 } from "@dxos/invariant";
946
1548
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
@@ -988,7 +1590,7 @@ var blast = (options = defaultOptions) => {
988
1590
  };
989
1591
  return [
990
1592
  // Cursor moved.
991
- EditorView4.updateListener.of((update2) => {
1593
+ EditorView5.updateListener.of((update2) => {
992
1594
  if (blaster?.node !== update2.view.scrollDOM) {
993
1595
  if (blaster) {
994
1596
  blaster.destroy();
@@ -1250,11 +1852,11 @@ var random = (min, max) => {
1250
1852
  };
1251
1853
 
1252
1854
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
1253
- import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
1855
+ import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1254
1856
 
1255
1857
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1256
1858
  import { RangeSetBuilder } from "@codemirror/state";
1257
- import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1859
+ import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1258
1860
 
1259
1861
  // packages/ui/react-ui-editor/src/extensions/command/state.ts
1260
1862
  import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
@@ -1420,7 +2022,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
1420
2022
  }
1421
2023
  }, {
1422
2024
  provide: (plugin) => [
1423
- EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2025
+ EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
1424
2026
  ]
1425
2027
  });
1426
2028
 
@@ -1431,7 +2033,7 @@ var command = (options) => {
1431
2033
  commandState,
1432
2034
  keymap3.of(commandKeyBindings),
1433
2035
  hintViewPlugin(options),
1434
- EditorView6.focusChangeEffect.of((_, focusing) => {
2036
+ EditorView7.focusChangeEffect.of((_, focusing) => {
1435
2037
  return focusing ? closeEffect.of(null) : null;
1436
2038
  })
1437
2039
  ];
@@ -1440,16 +2042,16 @@ var command = (options) => {
1440
2042
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1441
2043
  import { invertedEffects } from "@codemirror/commands";
1442
2044
  import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1443
- import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2045
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1444
2046
  import sortBy from "lodash.sortby";
1445
- import { useEffect, useMemo, useState } from "react";
2047
+ import { useEffect, useMemo as useMemo2 } from "react";
1446
2048
  import { debounce as debounce2 } from "@dxos/async";
1447
2049
  import { log as log4 } from "@dxos/log";
1448
2050
  import { nonNullable } from "@dxos/util";
1449
2051
 
1450
2052
  // packages/ui/react-ui-editor/src/extensions/selection.ts
1451
2053
  import { Transaction } from "@codemirror/state";
1452
- import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
2054
+ import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
1453
2055
  import { debounce } from "@dxos/async";
1454
2056
  import { invariant as invariant3 } from "@dxos/invariant";
1455
2057
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -1460,7 +2062,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1460
2062
  return {
1461
2063
  selection,
1462
2064
  scrollIntoView: !scrollTo,
1463
- effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
2065
+ effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
1464
2066
  yMargin: 96
1465
2067
  }) : void 0,
1466
2068
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -1502,7 +2104,7 @@ var selectionState = ({ getState, setState } = {}) => {
1502
2104
  // setStateDebounced(id, {});
1503
2105
  // },
1504
2106
  // }),
1505
- EditorView7.updateListener.of(({ view, transactions }) => {
2107
+ EditorView8.updateListener.of(({ view, transactions }) => {
1506
2108
  const id = view.state.facet(documentId);
1507
2109
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1508
2110
  return;
@@ -1583,7 +2185,7 @@ var commentsState = StateField4.define({
1583
2185
  return value;
1584
2186
  }
1585
2187
  });
1586
- var styles3 = EditorView8.theme({
2188
+ var styles3 = EditorView9.theme({
1587
2189
  ".cm-comment, .cm-comment-current": {
1588
2190
  margin: "0 -3px",
1589
2191
  padding: "3px",
@@ -1603,7 +2205,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
1603
2205
  "data-comment-id": id
1604
2206
  }
1605
2207
  });
1606
- var commentsDecorations = EditorView8.decorations.compute([
2208
+ var commentsDecorations = EditorView9.decorations.compute([
1607
2209
  commentsState
1608
2210
  ], (state) => {
1609
2211
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -1612,7 +2214,7 @@ var commentsDecorations = EditorView8.decorations.compute([
1612
2214
  if (!range) {
1613
2215
  log4.warn("Invalid range:", range, {
1614
2216
  F: __dxlog_file7,
1615
- L: 142,
2217
+ L: 144,
1616
2218
  S: void 0,
1617
2219
  C: (f, a) => f(...a)
1618
2220
  });
@@ -1626,7 +2228,7 @@ var commentsDecorations = EditorView8.decorations.compute([
1626
2228
  return Decoration4.set(decorations);
1627
2229
  });
1628
2230
  var commentClickedEffect = StateEffect3.define();
1629
- var handleCommentClick = EditorView8.domEventHandlers({
2231
+ var handleCommentClick = EditorView9.domEventHandlers({
1630
2232
  click: (event, view) => {
1631
2233
  let target = event.target;
1632
2234
  const editorRoot = view.dom;
@@ -1665,7 +2267,7 @@ var trackPastedComments = (onUpdate) => {
1665
2267
  }
1666
2268
  };
1667
2269
  return [
1668
- EditorView8.domEventHandlers({
2270
+ EditorView9.domEventHandlers({
1669
2271
  cut: handleTrack,
1670
2272
  copy: handleTrack
1671
2273
  }),
@@ -1687,7 +2289,7 @@ var trackPastedComments = (onUpdate) => {
1687
2289
  return effects;
1688
2290
  }),
1689
2291
  // Handle paste or the undo of comment deletion.
1690
- EditorView8.updateListener.of((update2) => {
2292
+ EditorView9.updateListener.of((update2) => {
1691
2293
  const restore = [];
1692
2294
  for (let i = 0; i < update2.transactions.length; i++) {
1693
2295
  const tr = update2.transactions[i];
@@ -1746,7 +2348,7 @@ var mapTrackedComment = (comment, changes) => ({
1746
2348
  var restoreCommentEffect = StateEffect3.define({
1747
2349
  map: mapTrackedComment
1748
2350
  });
1749
- var createComment = (view) => {
2351
+ var createComment2 = (view) => {
1750
2352
  const options = view.state.facet(optionsFacet);
1751
2353
  const { from, to } = view.state.selection.main;
1752
2354
  if (from === to) {
@@ -1791,7 +2393,7 @@ var comments = (options = {}) => {
1791
2393
  options.onCreate && keymap5.of([
1792
2394
  {
1793
2395
  key: shortcut,
1794
- run: callbackWrapper(createComment)
2396
+ run: callbackWrapper(createComment2)
1795
2397
  }
1796
2398
  ]),
1797
2399
  //
@@ -1827,7 +2429,7 @@ var comments = (options = {}) => {
1827
2429
  //
1828
2430
  // Track deleted ranges and update ranges for decorations.
1829
2431
  //
1830
- EditorView8.updateListener.of(({ view, state, changes }) => {
2432
+ EditorView9.updateListener.of(({ view, state, changes }) => {
1831
2433
  let mod = false;
1832
2434
  const { comments: comments2, ...value } = state.field(commentsState);
1833
2435
  changes.iterChanges((from, to, from2, to2) => {
@@ -1859,7 +2461,7 @@ var comments = (options = {}) => {
1859
2461
  //
1860
2462
  // Track selection/proximity.
1861
2463
  //
1862
- EditorView8.updateListener.of(({ view, state }) => {
2464
+ EditorView9.updateListener.of(({ view, state }) => {
1863
2465
  let min = Infinity;
1864
2466
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1865
2467
  const { head } = state.selection.main;
@@ -1913,7 +2515,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
1913
2515
  anchor: range.from
1914
2516
  } : void 0,
1915
2517
  effects: [
1916
- needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
2518
+ needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
1917
2519
  y: "center"
1918
2520
  } : void 0) : [],
1919
2521
  needsSelectionUpdate ? setSelection.of({
@@ -1924,415 +2526,179 @@ var scrollThreadIntoView = (view, id, center = true) => {
1924
2526
  }
1925
2527
  }
1926
2528
  };
1927
- var selectionOverlapsComment = (state) => {
1928
- const commentState = state.field(commentsState, false);
1929
- if (commentState === void 0) {
1930
- return false;
1931
- }
1932
- const { selection } = state;
1933
- for (const range of selection.ranges) {
1934
- if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
1935
- return true;
1936
- }
1937
- }
1938
- return false;
1939
- };
1940
- var hasActiveSelection = (state) => {
1941
- return state.selection.ranges.some((range) => !range.empty);
1942
- };
1943
- var ExternalCommentSync = class {
1944
- constructor(view, id, subscribe, getComments) {
1945
- this.destroy = () => {
1946
- this.unsubscribe();
1947
- };
1948
- const updateComments = () => {
1949
- const comments2 = getComments();
1950
- if (id === view.state.facet(documentId)) {
1951
- queueMicrotask(() => view.dispatch({
1952
- effects: setComments.of({
1953
- id,
1954
- comments: comments2
1955
- })
1956
- }));
1957
- }
1958
- };
1959
- this.unsubscribe = subscribe(updateComments);
1960
- }
1961
- };
1962
- var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
1963
- constructor(view) {
1964
- return new ExternalCommentSync(view, id, subscribe, getComments);
1965
- }
1966
- });
1967
- var useCommentState = () => {
1968
- const [state, setState] = useState({
1969
- comment: false,
1970
- selection: false
1971
- });
1972
- const observer = useMemo(() => EditorView8.updateListener.of((update2) => {
1973
- if (update2.docChanged || update2.selectionSet) {
1974
- setState({
1975
- comment: selectionOverlapsComment(update2.state),
1976
- selection: hasActiveSelection(update2.state)
1977
- });
1978
- }
1979
- }), []);
1980
- return [
1981
- state,
1982
- observer
1983
- ];
1984
- };
1985
- var useComments = (view, id, comments2) => {
1986
- useEffect(() => {
1987
- if (view) {
1988
- if (id === view.state.facet(documentId)) {
1989
- view.dispatch({
1990
- effects: setComments.of({
1991
- id,
1992
- comments: comments2 ?? []
1993
- })
1994
- });
1995
- }
1996
- }
1997
- });
1998
- };
1999
- var useCommentClickListener = (onCommentClick) => {
2000
- return useMemo(() => EditorView8.updateListener.of((update2) => {
2001
- update2.transactions.forEach((transaction) => {
2002
- transaction.effects.forEach((effect) => {
2003
- if (effect.is(commentClickedEffect)) {
2004
- onCommentClick(effect.value);
2005
- }
2006
- });
2007
- });
2008
- }), [
2009
- onCommentClick
2010
- ]);
2011
- };
2012
-
2013
- // packages/ui/react-ui-editor/src/extensions/debug.ts
2014
- import { syntaxTree } from "@codemirror/language";
2015
- import { StateField as StateField5 } from "@codemirror/state";
2016
- var debugNodeLogger = (log8 = console.log) => {
2017
- const logTokens = (state) => syntaxTree(state).iterate({
2018
- enter: (node) => log8(node.type)
2019
- });
2020
- return StateField5.define({
2021
- create: (state) => logTokens(state),
2022
- update: (_, tr) => logTokens(tr.state)
2023
- });
2024
- };
2025
-
2026
- // packages/ui/react-ui-editor/src/extensions/dnd.ts
2027
- import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
2028
- var styles4 = EditorView9.theme({
2029
- ".cm-dropCursor": {
2030
- borderLeft: "2px solid var(--dx-accentText)",
2031
- color: "var(--dx-accentText)",
2032
- padding: "0 4px"
2033
- },
2034
- ".cm-dropCursor:after": {
2035
- content: '"\u2190"'
2036
- }
2037
- });
2038
- var dropFile = (options = {}) => {
2039
- return [
2040
- styles4,
2041
- dropCursor(),
2042
- EditorView9.domEventHandlers({
2043
- drop: (event, view) => {
2044
- event.preventDefault();
2045
- const files = event.dataTransfer?.files;
2046
- const pos = view.posAtCoords(event);
2047
- if (files?.length && pos !== null) {
2048
- view.dispatch({
2049
- selection: {
2050
- anchor: pos
2051
- }
2052
- });
2053
- options.onDrop?.(view, {
2054
- files
2055
- });
2056
- }
2057
- }
2058
- })
2059
- ];
2060
- };
2061
-
2062
- // packages/ui/react-ui-editor/src/extensions/factories.ts
2063
- import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
2064
- import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
2065
- import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
2066
- import { searchKeymap } from "@codemirror/search";
2067
- import { EditorState } from "@codemirror/state";
2068
- import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2069
- import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2070
- import defaultsDeep2 from "lodash.defaultsdeep";
2071
- import merge from "lodash.merge";
2072
- import { generateName } from "@dxos/display-name";
2073
- import { log as log5 } from "@dxos/log";
2074
- import { hueTokens } from "@dxos/react-ui-theme";
2075
- import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2076
-
2077
- // packages/ui/react-ui-editor/src/extensions/focus.ts
2078
- import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2079
- import { EditorView as EditorView10 } from "@codemirror/view";
2080
- var focusEffect = StateEffect4.define();
2081
- var focusField = StateField6.define({
2082
- create: () => false,
2083
- update: (value, tr) => {
2084
- for (const effect of tr.effects) {
2085
- if (effect.is(focusEffect)) {
2086
- return effect.value;
2087
- }
2088
- }
2089
- return value;
2090
- }
2091
- });
2092
- var focus = [
2093
- focusField,
2094
- EditorView10.domEventHandlers({
2095
- focus: (event, view) => {
2096
- setTimeout(() => view.dispatch({
2097
- effects: focusEffect.of(true)
2098
- }));
2099
- },
2100
- blur: (event, view) => {
2101
- setTimeout(() => view.dispatch({
2102
- effects: focusEffect.of(false)
2103
- }));
2104
- }
2105
- })
2106
- ];
2107
-
2108
- // packages/ui/react-ui-editor/src/styles/markdown.ts
2109
- import { mx } from "@dxos/react-ui-theme";
2110
- var headings = {
2111
- 1: "text-4xl",
2112
- 2: "text-3xl",
2113
- 3: "text-2xl",
2114
- 4: "text-xl",
2115
- 5: "text-lg",
2116
- 6: "text-md"
2117
- };
2118
- var theme = {
2119
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2120
- codeMark: "font-mono text-primary-500",
2121
- mark: "opacity-50",
2122
- heading: (level) => {
2123
- return mx(headings[level], "dark:text-primary-400");
2124
- }
2125
- };
2126
-
2127
- // packages/ui/react-ui-editor/src/styles/tokens.ts
2128
- import get from "lodash.get";
2129
- import { tokens } from "@dxos/react-ui-theme";
2130
- var getToken = (path, defaultValue) => {
2131
- const value = get(tokens, path, defaultValue);
2132
- return value?.toString() ?? "";
2133
- };
2134
- var fontBody = getToken("fontFamily.body");
2135
- var fontMono = getToken("fontFamily.mono");
2136
-
2137
- // packages/ui/react-ui-editor/src/styles/theme.ts
2138
- var defaultTheme = {
2139
- "&": {},
2140
- "&.cm-focused": {
2141
- outline: "none"
2142
- },
2143
- /**
2144
- * Scroller
2145
- */
2146
- ".cm-scroller": {
2147
- overflowY: "auto"
2148
- },
2149
- /**
2150
- * Content
2151
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2152
- */
2153
- ".cm-content": {
2154
- padding: "unset",
2155
- fontFamily: fontBody,
2156
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2157
- fontSize: "16px",
2158
- lineHeight: 1.5,
2159
- color: "unset"
2160
- },
2161
- /**
2162
- * Gutters
2163
- * NOTE: Gutters should have the same top margin as the content.
2164
- * NOTE: They can't be transparent since the content needs to scroll below.
2165
- */
2166
- ".cm-gutters": {
2167
- background: "var(--surface-bg)",
2168
- borderRight: "none"
2169
- },
2170
- ".cm-gutter": {},
2171
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2172
- minWidth: "40px",
2173
- alignContent: "center"
2174
- },
2175
- /**
2176
- * Height is set to match the corresponding line.
2177
- */
2178
- ".cm-gutterElement": {
2179
- alignItems: "center",
2180
- fontSize: "16px"
2181
- },
2182
- /**
2183
- * Line.
2184
- */
2185
- ".cm-line": {
2186
- paddingInline: 0
2187
- },
2188
- ".cm-activeLine": {
2189
- background: "var(--dx-cmActiveLine)"
2190
- },
2191
- /**
2192
- * Cursor (layer).
2193
- */
2194
- ".cm-cursor, .cm-dropCursor": {
2195
- borderLeft: "2px solid var(--dx-cmCursor)"
2196
- },
2197
- ".cm-placeholder": {
2198
- color: "var(--dx-subdued)"
2199
- },
2200
- /**
2201
- * Selection (layer).
2202
- */
2203
- ".cm-selectionBackground": {
2204
- background: "var(--dx-cmSelection)"
2205
- },
2206
- /**
2207
- * Search.
2208
- * NOTE: Matches comment.
2209
- */
2210
- ".cm-searchMatch": {
2211
- margin: "0 -3px",
2212
- padding: "3px",
2213
- borderRadius: "3px",
2214
- background: "var(--dx-cmHighlightSurface)",
2215
- color: "var(--dx-cmHighlight)"
2216
- },
2217
- ".cm-searchMatch-selected": {
2218
- textDecoration: "underline"
2219
- },
2220
- /**
2221
- * Link.
2222
- */
2223
- ".cm-link": {
2224
- textDecorationLine: "underline",
2225
- textDecorationThickness: "1px",
2226
- textUnderlineOffset: "2px",
2227
- borderRadius: ".125rem"
2228
- },
2229
- ".cm-link > span": {
2230
- color: "var(--dx-accentText)"
2231
- },
2232
- /**
2233
- * Tooltip.
2234
- */
2235
- ".cm-tooltip": {
2236
- background: "var(--dx-base)"
2237
- },
2238
- ".cm-tooltip-below": {},
2239
- /**
2240
- * Autocomplete.
2241
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2242
- */
2243
- ".cm-tooltip.cm-tooltip-autocomplete": {
2244
- marginTop: "4px",
2245
- marginLeft: "-3px"
2246
- },
2247
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2248
- maxHeight: "20em"
2249
- },
2250
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2251
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2252
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2253
- paddingLeft: "4px !important",
2254
- borderBottom: "none !important",
2255
- color: "var(--dx-accentText)"
2256
- },
2257
- ".cm-tooltip.cm-completionInfo": {
2258
- width: "360px !important",
2259
- margin: "-10px 1px 0 1px",
2260
- padding: "8px !important",
2261
- borderColor: "var(--dx-separator)"
2262
- },
2263
- ".cm-completionIcon": {
2264
- display: "none"
2265
- },
2266
- ".cm-completionLabel": {
2267
- fontFamily: fontBody
2268
- },
2269
- ".cm-completionMatchedText": {
2270
- textDecoration: "none !important",
2271
- opacity: 0.5
2272
- },
2273
- /**
2274
- * Panels
2275
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2276
- *
2277
- * Find/replace panel.
2278
- * <div class="cm-announced">...</div>
2279
- * <div class="cm-scroller">...</div>
2280
- * <div class="cm-panels cm-panels-bottom">
2281
- * <div class="cm-search cm-panel">
2282
- * <input class="cm-textfield" />
2283
- * <button class="cm-button">...</button>
2284
- * <label><input type="checkbox" />...</label>
2285
- * </div>
2286
- * </div
2287
- */
2288
- // TODO(burdon): Implement custom panel (with icon buttons).
2289
- ".cm-panels": {},
2290
- ".cm-panel": {
2291
- fontFamily: fontBody,
2292
- backgroundColor: "var(--surface-bg)"
2293
- },
2294
- ".cm-panel input, .cm-panel button, .cm-panel label": {
2295
- color: "var(--dx-subdued)",
2296
- fontFamily: fontBody,
2297
- fontSize: "14px",
2298
- all: "unset",
2299
- margin: "3px !important",
2300
- padding: "2px 6px !important",
2301
- outline: "1px solid transparent"
2302
- },
2303
- ".cm-panel input, .cm-panel button": {
2304
- backgroundColor: "var(--dx-input)"
2305
- },
2306
- ".cm-panel input:focus, .cm-panel button:focus": {
2307
- outline: "1px solid var(--dx-accentFocusIndicator)"
2308
- },
2309
- ".cm-panel label": {
2310
- display: "inline-flex",
2311
- alignItems: "center",
2312
- cursor: "pointer"
2313
- },
2314
- ".cm-panel input.cm-textfield": {},
2315
- ".cm-panel input[type=checkbox]": {
2316
- width: "8px",
2317
- height: "8px",
2318
- marginRight: "6px !important",
2319
- padding: "2px !important",
2320
- color: "var(--dx-accentFocusIndicator)"
2321
- },
2322
- ".cm-panel button": {
2323
- "&:hover": {
2324
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
2325
- },
2326
- "&:active": {
2327
- backgroundColor: "var(--dx-accentSurfaceHover)"
2529
+ var selectionOverlapsComment = (state) => {
2530
+ const commentState = state.field(commentsState, false);
2531
+ if (commentState === void 0) {
2532
+ return false;
2533
+ }
2534
+ const { selection } = state;
2535
+ for (const range of selection.ranges) {
2536
+ if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2537
+ return true;
2538
+ }
2539
+ }
2540
+ return false;
2541
+ };
2542
+ var hasActiveSelection = (state) => {
2543
+ return state.selection.ranges.some((range) => !range.empty);
2544
+ };
2545
+ var ExternalCommentSync = class {
2546
+ constructor(view, id, subscribe, getComments) {
2547
+ this.destroy = () => {
2548
+ this.unsubscribe();
2549
+ };
2550
+ const updateComments = () => {
2551
+ const comments2 = getComments();
2552
+ if (id === view.state.facet(documentId)) {
2553
+ queueMicrotask(() => view.dispatch({
2554
+ effects: setComments.of({
2555
+ id,
2556
+ comments: comments2
2557
+ })
2558
+ }));
2559
+ }
2560
+ };
2561
+ this.unsubscribe = subscribe(updateComments);
2562
+ }
2563
+ };
2564
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
2565
+ constructor(view) {
2566
+ return new ExternalCommentSync(view, id, subscribe, getComments);
2567
+ }
2568
+ });
2569
+ var useCommentState = (state) => {
2570
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2571
+ if (update2.docChanged || update2.selectionSet) {
2572
+ state.comment = selectionOverlapsComment(update2.state);
2573
+ state.selection = hasActiveSelection(update2.state);
2574
+ }
2575
+ }), [
2576
+ state
2577
+ ]);
2578
+ };
2579
+ var useComments = (view, id, comments2) => {
2580
+ useEffect(() => {
2581
+ if (view) {
2582
+ if (id === view.state.facet(documentId)) {
2583
+ view.dispatch({
2584
+ effects: setComments.of({
2585
+ id,
2586
+ comments: comments2 ?? []
2587
+ })
2588
+ });
2589
+ }
2328
2590
  }
2591
+ });
2592
+ };
2593
+ var useCommentClickListener = (onCommentClick) => {
2594
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2595
+ update2.transactions.forEach((transaction) => {
2596
+ transaction.effects.forEach((effect) => {
2597
+ if (effect.is(commentClickedEffect)) {
2598
+ onCommentClick(effect.value);
2599
+ }
2600
+ });
2601
+ });
2602
+ }), [
2603
+ onCommentClick
2604
+ ]);
2605
+ };
2606
+
2607
+ // packages/ui/react-ui-editor/src/extensions/debug.ts
2608
+ import { syntaxTree } from "@codemirror/language";
2609
+ import { StateField as StateField5 } from "@codemirror/state";
2610
+ var debugNodeLogger = (log8 = console.log) => {
2611
+ const logTokens = (state) => syntaxTree(state).iterate({
2612
+ enter: (node) => log8(node.type)
2613
+ });
2614
+ return StateField5.define({
2615
+ create: (state) => logTokens(state),
2616
+ update: (_, tr) => logTokens(tr.state)
2617
+ });
2618
+ };
2619
+
2620
+ // packages/ui/react-ui-editor/src/extensions/dnd.ts
2621
+ import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2622
+ var styles4 = EditorView10.theme({
2623
+ ".cm-dropCursor": {
2624
+ borderLeft: "2px solid var(--dx-accentText)",
2625
+ color: "var(--dx-accentText)",
2626
+ padding: "0 4px"
2329
2627
  },
2330
- ".cm-panel.cm-search": {
2331
- padding: "4px",
2332
- borderTop: "1px solid var(--dx-separator)"
2628
+ ".cm-dropCursor:after": {
2629
+ content: '"\u2190"'
2333
2630
  }
2631
+ });
2632
+ var dropFile = (options = {}) => {
2633
+ return [
2634
+ styles4,
2635
+ dropCursor(),
2636
+ EditorView10.domEventHandlers({
2637
+ drop: (event, view) => {
2638
+ event.preventDefault();
2639
+ const files = event.dataTransfer?.files;
2640
+ const pos = view.posAtCoords(event);
2641
+ if (files?.length && pos !== null) {
2642
+ view.dispatch({
2643
+ selection: {
2644
+ anchor: pos
2645
+ }
2646
+ });
2647
+ options.onDrop?.(view, {
2648
+ files
2649
+ });
2650
+ }
2651
+ }
2652
+ })
2653
+ ];
2334
2654
  };
2335
2655
 
2656
+ // packages/ui/react-ui-editor/src/extensions/factories.ts
2657
+ import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
2658
+ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
2659
+ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
2660
+ import { searchKeymap } from "@codemirror/search";
2661
+ import { EditorState } from "@codemirror/state";
2662
+ import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2663
+ import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2664
+ import defaultsDeep2 from "lodash.defaultsdeep";
2665
+ import merge from "lodash.merge";
2666
+ import { generateName } from "@dxos/display-name";
2667
+ import { log as log5 } from "@dxos/log";
2668
+ import { hueTokens } from "@dxos/react-ui-theme";
2669
+ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2670
+
2671
+ // packages/ui/react-ui-editor/src/extensions/focus.ts
2672
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2673
+ import { EditorView as EditorView11 } from "@codemirror/view";
2674
+ var focusEffect = StateEffect4.define();
2675
+ var focusField = StateField6.define({
2676
+ create: () => false,
2677
+ update: (value, tr) => {
2678
+ for (const effect of tr.effects) {
2679
+ if (effect.is(focusEffect)) {
2680
+ return effect.value;
2681
+ }
2682
+ }
2683
+ return value;
2684
+ }
2685
+ });
2686
+ var focus = [
2687
+ focusField,
2688
+ EditorView11.domEventHandlers({
2689
+ focus: (event, view) => {
2690
+ setTimeout(() => view.dispatch({
2691
+ effects: focusEffect.of(true)
2692
+ }));
2693
+ },
2694
+ blur: (event, view) => {
2695
+ setTimeout(() => view.dispatch({
2696
+ effects: focusEffect.of(false)
2697
+ }));
2698
+ }
2699
+ })
2700
+ ];
2701
+
2336
2702
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2337
2703
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2338
2704
  var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
@@ -2358,7 +2724,7 @@ var createBasicExtensions = (_props) => {
2358
2724
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2359
2725
  return [
2360
2726
  // NOTE: Doesn't catch errors in keymap functions.
2361
- EditorView11.exceptionSink.of((err) => {
2727
+ EditorView12.exceptionSink.of((err) => {
2362
2728
  log5.catch(err, void 0, {
2363
2729
  F: __dxlog_file8,
2364
2730
  L: 96,
@@ -2377,11 +2743,11 @@ var createBasicExtensions = (_props) => {
2377
2743
  props.highlightActiveLine && highlightActiveLine(),
2378
2744
  props.history && history(),
2379
2745
  props.lineNumbers && lineNumbers(),
2380
- props.lineWrapping && EditorView11.lineWrapping,
2746
+ props.lineWrapping && EditorView12.lineWrapping,
2381
2747
  props.placeholder && placeholder(props.placeholder),
2382
2748
  props.readonly && [
2383
2749
  EditorState.readOnly.of(true),
2384
- EditorView11.editable.of(false)
2750
+ EditorView12.editable.of(false)
2385
2751
  ],
2386
2752
  props.scrollPastEnd && scrollPastEnd(),
2387
2753
  props.tabSize && EditorState.tabSize.of(props.tabSize),
@@ -2410,14 +2776,14 @@ var defaultThemeSlots = {
2410
2776
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2411
2777
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2412
2778
  return [
2413
- EditorView11.darkTheme.of(themeMode === "dark"),
2414
- EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2779
+ EditorView12.darkTheme.of(themeMode === "dark"),
2780
+ EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2415
2781
  // https://github.com/codemirror/theme-one-dark
2416
2782
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2417
- slots.editor?.className && EditorView11.editorAttributes.of({
2783
+ slots.editor?.className && EditorView12.editorAttributes.of({
2418
2784
  class: slots.editor.className
2419
2785
  }),
2420
- slots.content?.className && EditorView11.contentAttributes.of({
2786
+ slots.content?.className && EditorView12.contentAttributes.of({
2421
2787
  class: slots.content.className
2422
2788
  })
2423
2789
  ].filter(isNotFalsy3);
@@ -2446,8 +2812,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2446
2812
 
2447
2813
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2448
2814
  import { codeFolding, foldGutter } from "@codemirror/language";
2449
- import { EditorView as EditorView12 } from "@codemirror/view";
2450
- import React2 from "react";
2815
+ import { EditorView as EditorView13 } from "@codemirror/view";
2816
+ import React3 from "react";
2451
2817
  import { Icon } from "@dxos/react-ui";
2452
2818
  var folding = (_props = {}) => [
2453
2819
  codeFolding({
@@ -2460,7 +2826,7 @@ var folding = (_props = {}) => [
2460
2826
  const el = createElement("div", {
2461
2827
  className: "flex h-full items-center"
2462
2828
  });
2463
- return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
2829
+ return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
2464
2830
  icon: "ph--caret-right--regular",
2465
2831
  size: 3,
2466
2832
  classNames: [
@@ -2470,7 +2836,7 @@ var folding = (_props = {}) => [
2470
2836
  }));
2471
2837
  }
2472
2838
  }),
2473
- EditorView12.theme({
2839
+ EditorView13.theme({
2474
2840
  ".cm-foldGutter": {
2475
2841
  opacity: 0.3,
2476
2842
  transition: "opacity 0.3s",
@@ -2483,14 +2849,14 @@ var folding = (_props = {}) => [
2483
2849
  ];
2484
2850
 
2485
2851
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2486
- import { EditorView as EditorView13 } from "@codemirror/view";
2852
+ import { EditorView as EditorView14 } from "@codemirror/view";
2487
2853
  var listener = ({ onFocus, onChange }) => {
2488
2854
  const extensions = [];
2489
- onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
2855
+ onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
2490
2856
  onFocus(focusing);
2491
2857
  return null;
2492
2858
  }));
2493
- onChange && extensions.push(EditorView13.updateListener.of((update2) => {
2859
+ onChange && extensions.push(EditorView14.updateListener.of((update2) => {
2494
2860
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2495
2861
  }));
2496
2862
  return extensions;
@@ -2500,8 +2866,8 @@ var listener = ({ onFocus, onChange }) => {
2500
2866
  import { snippet } from "@codemirror/autocomplete";
2501
2867
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2502
2868
  import { EditorSelection } from "@codemirror/state";
2503
- import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
2504
- import { useMemo as useMemo2, useState as useState2 } from "react";
2869
+ import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
2870
+ import { useMemo as useMemo3 } from "react";
2505
2871
  var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2506
2872
  var Inline;
2507
2873
  (function(Inline2) {
@@ -3588,65 +3954,56 @@ var getFormatting = (state) => {
3588
3954
  listStyle: listStyle || null
3589
3955
  };
3590
3956
  };
3591
- var useFormattingState = () => {
3592
- const [state, setState] = useState2();
3593
- const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
3957
+ var useFormattingState = (state) => {
3958
+ return useMemo3(() => EditorView15.updateListener.of((update2) => {
3594
3959
  if (update2.docChanged || update2.selectionSet) {
3595
- setState((prevState) => {
3596
- const newState = getFormatting(update2.state);
3597
- if (!prevState || !formattingEquals(prevState, newState)) {
3598
- return newState;
3599
- }
3600
- return prevState;
3960
+ Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
3961
+ state[key] = active;
3601
3962
  });
3602
3963
  }
3603
3964
  }), []);
3604
- return [
3605
- state,
3606
- observer
3607
- ];
3608
3965
  };
3609
3966
 
3610
- // packages/ui/react-ui-editor/src/extensions/markdown/action.ts
3611
- var processAction = (view, action) => {
3967
+ // packages/ui/react-ui-editor/src/extensions/markdown/editorAction.ts
3968
+ var processEditorPayload = (view, { type, data }) => {
3612
3969
  let inlineType, listType;
3613
- switch (action.type) {
3970
+ switch (type) {
3614
3971
  case "heading":
3615
- setHeading(parseInt(action.data))(view);
3972
+ setHeading(parseInt(data))(view);
3616
3973
  break;
3617
3974
  case "strong":
3618
3975
  case "emphasis":
3619
3976
  case "strikethrough":
3620
3977
  case "code":
3621
- inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3622
- (typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
3978
+ inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3979
+ (typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
3623
3980
  break;
3624
3981
  case "list-ordered":
3625
3982
  case "list-bullet":
3626
3983
  case "list-task":
3627
- listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
3628
- (action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
3984
+ listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
3985
+ (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
3629
3986
  break;
3630
3987
  case "blockquote":
3631
- (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
3988
+ (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
3632
3989
  break;
3633
3990
  case "codeblock":
3634
- (action.data === false ? removeCodeblock : addCodeblock)(view);
3991
+ (data === false ? removeCodeblock : addCodeblock)(view);
3635
3992
  break;
3636
3993
  case "table":
3637
3994
  insertTable(view);
3638
3995
  break;
3639
3996
  case "link":
3640
- (action.data === false ? removeLink : addLink())(view);
3997
+ (data === false ? removeLink : addLink())(view);
3641
3998
  break;
3642
3999
  case "image":
3643
4000
  addLink({
3644
- url: action.data,
4001
+ url: data,
3645
4002
  image: true
3646
4003
  })(view);
3647
4004
  break;
3648
4005
  case "comment":
3649
- createComment(view);
4006
+ createComment2(view);
3650
4007
  break;
3651
4008
  }
3652
4009
  requestAnimationFrame(() => {
@@ -3910,9 +4267,9 @@ var convertTreeToJson = (state) => {
3910
4267
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3911
4268
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3912
4269
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
3913
- import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4270
+ import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3914
4271
  import { invariant as invariant4 } from "@dxos/invariant";
3915
- import { mx as mx2 } from "@dxos/react-ui-theme";
4272
+ import { mx as mx4 } from "@dxos/react-ui-theme";
3916
4273
 
3917
4274
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
3918
4275
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
@@ -4061,7 +4418,7 @@ var getValidUrl = (str) => {
4061
4418
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
4062
4419
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4063
4420
  import { StateField as StateField8 } from "@codemirror/state";
4064
- import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
4421
+ import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4065
4422
  var image = (_options = {}) => {
4066
4423
  return [
4067
4424
  StateField8.define({
@@ -4089,7 +4446,7 @@ var image = (_options = {}) => {
4089
4446
  add: buildDecorations(from, to, tr.state)
4090
4447
  });
4091
4448
  },
4092
- provide: (field) => EditorView15.decorations.from(field)
4449
+ provide: (field) => EditorView16.decorations.from(field)
4093
4450
  })
4094
4451
  ];
4095
4452
  };
@@ -4149,10 +4506,10 @@ var ImageWidget = class extends WidgetType3 {
4149
4506
  };
4150
4507
 
4151
4508
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4152
- import { EditorView as EditorView16 } from "@codemirror/view";
4509
+ import { EditorView as EditorView17 } from "@codemirror/view";
4153
4510
  var bulletListIndentationWidth = 24;
4154
4511
  var orderedListIndentationWidth = 36;
4155
- var formattingStyles = EditorView16.theme({
4512
+ var formattingStyles = EditorView17.theme({
4156
4513
  /**
4157
4514
  * Horizontal rule.
4158
4515
  */
@@ -4246,18 +4603,39 @@ var formattingStyles = EditorView16.theme({
4246
4603
  height: "auto",
4247
4604
  borderTop: "0.5rem solid transparent",
4248
4605
  borderBottom: "0.5rem solid transparent"
4606
+ },
4607
+ ".cm-image-with-loader": {
4608
+ display: "block",
4609
+ opacity: "0",
4610
+ transitionDuration: "350ms",
4611
+ transitionProperty: "opacity"
4612
+ },
4613
+ ".cm-image-with-loader.cm-loaded-image": {
4614
+ opacity: "1"
4615
+ },
4616
+ ".cm-image-wrapper": {
4617
+ "grid-template-columns": "1fr",
4618
+ display: "grid",
4619
+ margin: "0.5rem 0",
4620
+ overflow: "hidden",
4621
+ transitionDuration: "350ms",
4622
+ transitionProperty: "height",
4623
+ "& > *": {
4624
+ "grid-row-start": 1,
4625
+ "grid-column-start": 1
4626
+ }
4249
4627
  }
4250
4628
  });
4251
4629
 
4252
4630
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4253
4631
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4254
4632
  import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4255
- import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4633
+ import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4256
4634
  var table = (options = {}) => {
4257
4635
  return StateField9.define({
4258
4636
  create: (state) => update(state, options),
4259
4637
  update: (_, tr) => update(tr.state, options),
4260
- provide: (field) => EditorView17.decorations.from(field)
4638
+ provide: (field) => EditorView18.decorations.from(field)
4261
4639
  });
4262
4640
  };
4263
4641
  var update = (state, _options) => {
@@ -4389,7 +4767,7 @@ var CheckboxWidget = class extends WidgetType5 {
4389
4767
  }
4390
4768
  toDOM(view) {
4391
4769
  const input = document.createElement("input");
4392
- input.className = "cm-task-checkbox ch-checkbox";
4770
+ input.className = "cm-task-checkbox dx-checkbox";
4393
4771
  input.type = "checkbox";
4394
4772
  input.tabIndex = -1;
4395
4773
  input.checked = this._checked;
@@ -4441,16 +4819,16 @@ var TextWidget = class extends WidgetType5 {
4441
4819
  };
4442
4820
  var hide = Decoration7.replace({});
4443
4821
  var blockQuote = Decoration7.line({
4444
- class: mx2("cm-blockquote")
4822
+ class: mx4("cm-blockquote")
4445
4823
  });
4446
4824
  var fencedCodeLine = Decoration7.line({
4447
- class: mx2("cm-code cm-codeblock-line")
4825
+ class: mx4("cm-code cm-codeblock-line")
4448
4826
  });
4449
4827
  var fencedCodeLineFirst = Decoration7.line({
4450
- class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
4828
+ class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
4451
4829
  });
4452
4830
  var fencedCodeLineLast = Decoration7.line({
4453
- class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
4831
+ class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
4454
4832
  });
4455
4833
  var commentBlockLine = fencedCodeLine;
4456
4834
  var commentBlockLineFirst = fencedCodeLineFirst;
@@ -4791,9 +5169,9 @@ var decorateMarkdown = (options = {}) => {
4791
5169
  }
4792
5170
  }, {
4793
5171
  provide: (plugin) => [
4794
- EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4795
- EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4796
- EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5172
+ EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5173
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5174
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4797
5175
  ]
4798
5176
  }),
4799
5177
  image(),
@@ -4980,428 +5358,29 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4980
5358
  ];
4981
5359
  };
4982
5360
 
4983
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4984
- var iconStyles = getSize(5);
4985
- var buttonStyles = "min-bs-0 p-1";
4986
- var tooltipProps = {
4987
- side: "top",
4988
- classNames: "z-10"
4989
- };
4990
- var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
4991
- role: "separator",
4992
- className: "grow"
4993
- });
4994
- var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4995
- var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4996
- return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
4997
- onAction,
4998
- state
4999
- }, /* @__PURE__ */ React3.createElement(ElevationProvider, {
5000
- elevation: "positioned"
5001
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
5002
- classNames: [
5003
- "p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
5004
- classNames
5005
- ],
5006
- style: {
5007
- contain: "layout"
5008
- }
5009
- }, children)));
5010
- };
5011
- var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
5012
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5013
- asChild: true
5014
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, {
5015
- variant: "ghost",
5016
- ...props,
5017
- classNames: buttonStyles
5018
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5019
- className: iconStyles
5020
- }), /* @__PURE__ */ React3.createElement("span", {
5021
- className: "sr-only"
5022
- }, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5023
- };
5024
- var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
5025
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5026
- asChild: true
5027
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5028
- variant: "ghost",
5029
- ...props,
5030
- classNames: buttonStyles
5031
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5032
- className: iconStyles
5033
- }), /* @__PURE__ */ React3.createElement("span", {
5034
- className: "sr-only"
5035
- }, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5036
- };
5037
- var HeadingIcons = {
5038
- "0": Paragraph,
5039
- "1": TextHOne,
5040
- "2": TextHTwo,
5041
- "3": TextHThree,
5042
- "4": TextHFour,
5043
- "5": TextHFive,
5044
- "6": TextHSix
5045
- };
5046
- var MarkdownHeading = () => {
5047
- const { t } = useTranslation(translationKey);
5048
- const { onAction, state } = useToolbarContext("MarkdownFormatting");
5049
- const blockType = state ? state.blockType : "paragraph";
5050
- const header = blockType && /heading(\d)/.exec(blockType);
5051
- const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
5052
- const HeadingIcon = HeadingIcons[value ?? "0"];
5053
- const suppressNextTooltip = useRef(false);
5054
- const [tooltipOpen, setTooltipOpen] = useState3(false);
5055
- const [selectOpen, setSelectOpen] = useState3(false);
5056
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
5057
- open: tooltipOpen,
5058
- onOpenChange: (nextOpen) => {
5059
- if (nextOpen && suppressNextTooltip.current) {
5060
- suppressNextTooltip.current = false;
5061
- return setTooltipOpen(false);
5062
- } else {
5063
- return setTooltipOpen(nextOpen);
5064
- }
5065
- }
5066
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
5067
- open: selectOpen,
5068
- onOpenChange: (nextOpen) => {
5069
- if (!nextOpen) {
5070
- suppressNextTooltip.current = true;
5071
- }
5072
- return setSelectOpen(nextOpen);
5073
- }
5074
- }, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5075
- asChild: true
5076
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5077
- asChild: true
5078
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
5079
- asChild: true
5080
- }, /* @__PURE__ */ React3.createElement(Button, {
5081
- variant: "ghost",
5082
- classNames: buttonStyles,
5083
- disabled: value === null
5084
- }, /* @__PURE__ */ React3.createElement("span", {
5085
- className: "sr-only"
5086
- }, t("heading label")), /* @__PURE__ */ React3.createElement(HeadingIcon, {
5087
- className: iconStyles
5088
- }), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
5089
- classNames: "is-min md:is-min",
5090
- onCloseAutoFocus: (e) => e.preventDefault()
5091
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
5092
- const Icon2 = HeadingIcons[level];
5093
- return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
5094
- key: level,
5095
- checked: value === level,
5096
- onClick: () => onAction?.({
5097
- type: "heading",
5098
- data: level
5099
- })
5100
- }, /* @__PURE__ */ React3.createElement("span", {
5101
- className: "sr-only"
5102
- }, t("heading level label", {
5103
- count: parseInt(level)
5104
- })), /* @__PURE__ */ React3.createElement(Icon2, {
5105
- className: iconStyles
5106
- }), /* @__PURE__ */ React3.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React3.createElement(Check, null)));
5107
- })), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5108
- };
5109
- var markdownStyles = [
5110
- {
5111
- type: "strong",
5112
- Icon: TextB,
5113
- getState: (state) => !!state?.strong
5114
- },
5115
- {
5116
- type: "emphasis",
5117
- Icon: TextItalic,
5118
- getState: (state) => !!state?.emphasis
5119
- },
5120
- {
5121
- type: "strikethrough",
5122
- Icon: TextStrikethrough,
5123
- getState: (state) => !!state?.strikethrough
5124
- },
5125
- {
5126
- type: "code",
5127
- Icon: Code,
5128
- getState: (state) => !!state?.code
5129
- },
5130
- {
5131
- type: "link",
5132
- Icon: Link,
5133
- getState: (state) => !!state?.link
5134
- }
5135
- ];
5136
- var MarkdownStyles = () => {
5137
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5138
- const { t } = useTranslation(translationKey);
5139
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5140
- type: "multiple",
5141
- value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
5142
- }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5143
- key: type,
5144
- value: type,
5145
- Icon: Icon2,
5146
- disabled: state?.blockType === "codeblock",
5147
- onClick: state ? () => onAction?.({
5148
- type,
5149
- data: !getState(state)
5150
- }) : void 0
5151
- }, t(`${type} label`))));
5152
- };
5153
- var markdownLists = [
5154
- {
5155
- type: "list-bullet",
5156
- Icon: ListBullets,
5157
- getState: (state) => state.listStyle === "bullet"
5158
- },
5159
- {
5160
- type: "list-ordered",
5161
- Icon: ListNumbers,
5162
- getState: (state) => state.listStyle === "ordered"
5163
- },
5164
- {
5165
- type: "list-task",
5166
- Icon: ListChecks,
5167
- getState: (state) => state.listStyle === "task"
5168
- }
5169
- ];
5170
- var MarkdownLists = () => {
5171
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5172
- const { t } = useTranslation(translationKey);
5173
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5174
- type: "single",
5175
- value: state?.listStyle ? `list-${state.listStyle}` : ""
5176
- }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5177
- key: type,
5178
- value: type,
5179
- Icon: Icon2,
5180
- onClick: state ? () => onAction?.({
5181
- type,
5182
- data: !getState(state)
5183
- }) : void 0
5184
- }, t(`${type} label`))));
5185
- };
5186
- var markdownBlocks = [
5187
- {
5188
- type: "blockquote",
5189
- Icon: Quotes,
5190
- getState: (state) => !!state?.blockQuote
5191
- },
5192
- {
5193
- type: "codeblock",
5194
- Icon: CodeBlock,
5195
- getState: (state) => state.blockType === "codeblock"
5196
- },
5197
- {
5198
- type: "table",
5199
- Icon: Table2,
5200
- getState: (state) => state.blockType === "tablecell",
5201
- disabled: (state) => !state.blankLine
5202
- }
5203
- ];
5204
- var MarkdownBlocks = () => {
5205
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5206
- const { t } = useTranslation(translationKey);
5207
- const value = markdownBlocks.find(({ getState }) => state && getState(state));
5208
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5209
- type: "single",
5210
- value: value?.type ?? ""
5211
- }, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5212
- key: type,
5213
- value: type,
5214
- Icon: Icon2,
5215
- disabled: !state || disabled?.(state),
5216
- onClick: state ? () => onAction?.({
5217
- type,
5218
- data: !getState(state)
5219
- }) : void 0
5220
- }, t(`${type} label`))));
5221
- };
5222
- var MarkdownStandard = () => /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(MarkdownHeading, null), /* @__PURE__ */ React3.createElement(MarkdownStyles, null), /* @__PURE__ */ React3.createElement(MarkdownLists, null), /* @__PURE__ */ React3.createElement(MarkdownBlocks, null));
5223
- var MarkdownCustom = ({ onUpload } = {}) => {
5224
- const { onAction } = useToolbarContext("MarkdownStyles");
5225
- const { t } = useTranslation(translationKey);
5226
- const { acceptedFiles, getInputProps, open } = useDropzone({
5227
- multiple: false,
5228
- noDrag: true,
5229
- accept: {
5230
- "image/*": [
5231
- ".jpg",
5232
- ".jpeg",
5233
- ".png",
5234
- ".gif"
5235
- ]
5236
- }
5237
- });
5238
- useEffect2(() => {
5239
- if (onUpload && acceptedFiles.length) {
5240
- requestAnimationFrame(async () => {
5241
- const f = acceptedFiles[0];
5242
- const file = new File([
5243
- f
5244
- ], f.name, {
5245
- type: f.type,
5246
- lastModified: f.lastModified
5247
- });
5248
- const info = await onUpload(file);
5249
- if (info) {
5250
- onAction?.({
5251
- type: "image",
5252
- data: info.url
5253
- });
5254
- }
5255
- });
5256
- }
5257
- }, [
5258
- acceptedFiles
5259
- ]);
5260
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("input", getInputProps()), /* @__PURE__ */ React3.createElement(ToolbarButton, {
5261
- value: "image",
5262
- Icon: Image,
5263
- onClick: () => open()
5264
- }, t("image label")));
5265
- };
5266
- var ViewModeIcons = {
5267
- preview: PencilSimple,
5268
- readonly: PencilSimpleSlash,
5269
- source: MarkdownLogo
5270
- };
5271
- var MarkdownView = ({ mode }) => {
5272
- const { t } = useTranslation(translationKey);
5273
- const { onAction } = useToolbarContext("ViewMode");
5274
- const ModeIcon = ViewModeIcons[mode ?? "preview"];
5275
- const suppressNextTooltip = useRef(false);
5276
- const [tooltipOpen, setTooltipOpen] = useState3(false);
5277
- const [selectOpen, setSelectOpen] = useState3(false);
5278
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
5279
- open: tooltipOpen,
5280
- onOpenChange: (nextOpen) => {
5281
- if (nextOpen && suppressNextTooltip.current) {
5282
- suppressNextTooltip.current = false;
5283
- return setTooltipOpen(false);
5284
- } else {
5285
- return setTooltipOpen(nextOpen);
5286
- }
5287
- }
5288
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
5289
- open: selectOpen,
5290
- onOpenChange: (nextOpen) => {
5291
- if (!nextOpen) {
5292
- suppressNextTooltip.current = true;
5293
- }
5294
- return setSelectOpen(nextOpen);
5295
- }
5296
- }, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5297
- asChild: true
5298
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5299
- asChild: true
5300
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
5301
- asChild: true
5302
- }, /* @__PURE__ */ React3.createElement(Button, {
5303
- variant: "ghost",
5304
- classNames: buttonStyles
5305
- }, /* @__PURE__ */ React3.createElement("span", {
5306
- className: "sr-only"
5307
- }, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
5308
- className: iconStyles
5309
- }), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
5310
- classNames: "is-min md:is-min",
5311
- onCloseAutoFocus: (e) => e.preventDefault()
5312
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
5313
- const Icon2 = ViewModeIcons[value];
5314
- return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
5315
- key: value,
5316
- checked: value === mode,
5317
- onClick: () => onAction?.({
5318
- type: "view-mode",
5319
- data: value
5320
- })
5321
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5322
- className: iconStyles
5323
- }), /* @__PURE__ */ React3.createElement("span", {
5324
- className: "whitespace-nowrap grow"
5325
- }, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
5326
- className: value === mode ? "visible" : "invisible"
5327
- }));
5328
- })), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5329
- };
5330
- var MarkdownActions = () => {
5331
- const { onAction, state } = useToolbarContext("MarkdownActions");
5332
- const { t } = useTranslation(translationKey);
5333
- let commentToolTipKey = "comment label";
5334
- if (state?.comment) {
5335
- commentToolTipKey = "selection overlaps existing comment label";
5336
- } else if (state?.selection === false) {
5337
- commentToolTipKey = "select text to comment label";
5338
- }
5339
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
5340
- value: "search",
5341
- Icon: MagnifyingGlass,
5342
- onClick: () => onAction?.({
5343
- type: "search"
5344
- })
5345
- }, t("search label")), /* @__PURE__ */ React3.createElement(ToolbarButton, {
5346
- value: "comment",
5347
- Icon: ChatText,
5348
- "data-testid": "editor.toolbar.comment",
5349
- onClick: () => onAction?.({
5350
- type: "comment"
5351
- }),
5352
- disabled: !state || state.comment || !state.selection
5353
- }, t(commentToolTipKey)));
5354
- };
5355
- var Toolbar = {
5356
- Root: ToolbarRoot,
5357
- Button: ToolbarToggleButton,
5358
- Separator: ToolbarSeparator,
5359
- View: MarkdownView,
5360
- Markdown: MarkdownStandard,
5361
- Custom: MarkdownCustom,
5362
- Actions: MarkdownActions
5363
- };
5364
-
5365
- // packages/ui/react-ui-editor/src/defaults.ts
5366
- import { EditorView as EditorView19 } from "@codemirror/view";
5367
- import { mx as mx3 } from "@dxos/react-ui-theme";
5368
- var margin = "!mt-[1rem]";
5369
- var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5370
- var editorFullWidth = mx3(margin);
5371
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5372
- var editorGutter = EditorView19.theme({
5373
- // Match margin from content.
5374
- ".cm-gutters": {
5375
- marginTop: "16px",
5376
- paddingRight: "1rem"
5377
- }
5378
- });
5379
- var editorMonospace = EditorView19.theme({
5380
- ".cm-content": {
5381
- fontFamily: fontMono
5382
- }
5383
- });
5384
-
5385
5361
  // packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
5362
+ import { useCallback as useCallback2 } from "react";
5386
5363
  var useActionHandler = (view) => {
5387
- return (action) => view && processAction(view, action);
5364
+ return useCallback2((action) => view && processEditorPayload(view, action.properties), [
5365
+ view
5366
+ ]);
5388
5367
  };
5389
5368
 
5390
5369
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5391
5370
  import { EditorState as EditorState2 } from "@codemirror/state";
5392
5371
  import { EditorView as EditorView20 } from "@codemirror/view";
5393
5372
  import { useFocusableGroup } from "@fluentui/react-tabster";
5394
- import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5373
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
5395
5374
  import { log as log7 } from "@dxos/log";
5396
5375
  import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5397
5376
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5398
5377
  var instanceCount = 0;
5399
5378
  var useTextEditor = (props = {}, deps = []) => {
5400
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
5401
- const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
5402
- const [view, setView] = useState4();
5403
- const parentRef = useRef2(null);
5404
- useEffect3(() => {
5379
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5380
+ const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
5381
+ const [view, setView] = useState();
5382
+ const parentRef = useRef(null);
5383
+ useEffect2(() => {
5405
5384
  let view2;
5406
5385
  if (parentRef.current) {
5407
5386
  log7("create", {
@@ -5475,7 +5454,7 @@ var useTextEditor = (props = {}, deps = []) => {
5475
5454
  view2?.destroy();
5476
5455
  };
5477
5456
  }, deps);
5478
- useEffect3(() => {
5457
+ useEffect2(() => {
5479
5458
  if (view) {
5480
5459
  if (scrollTo || selection) {
5481
5460
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5502,7 +5481,7 @@ var useTextEditor = (props = {}, deps = []) => {
5502
5481
  scrollTo,
5503
5482
  selection
5504
5483
  ]);
5505
- useEffect3(() => {
5484
+ useEffect2(() => {
5506
5485
  if (view && autoFocus) {
5507
5486
  view.focus();
5508
5487
  }
@@ -5516,7 +5495,7 @@ var useTextEditor = (props = {}, deps = []) => {
5516
5495
  Escape: view?.state.facet(editorInputMode).noTabster
5517
5496
  }
5518
5497
  });
5519
- const handleKeyUp = useCallback((event) => {
5498
+ const handleKeyUp = useCallback3((event) => {
5520
5499
  const { key, target, currentTarget } = event;
5521
5500
  if (target === currentTarget) {
5522
5501
  switch (key) {
@@ -5545,6 +5524,7 @@ export {
5545
5524
  EditorInputMode,
5546
5525
  EditorInputModes,
5547
5526
  EditorState3 as EditorState,
5527
+ EditorToolbar,
5548
5528
  EditorView21 as EditorView,
5549
5529
  EditorViewMode,
5550
5530
  EditorViewModes,
@@ -5554,7 +5534,6 @@ export {
5554
5534
  RemoteSelectionsDecorator,
5555
5535
  SpaceAwarenessProvider,
5556
5536
  TextKind,
5557
- Toolbar,
5558
5537
  addBlockquote,
5559
5538
  addCodeblock,
5560
5539
  addLink,
@@ -5573,8 +5552,10 @@ export {
5573
5552
  commentsState,
5574
5553
  convertTreeToJson,
5575
5554
  createBasicExtensions,
5576
- createComment,
5555
+ createComment2 as createComment,
5577
5556
  createDataExtensions,
5557
+ createEditorAction,
5558
+ createEditorActionGroup,
5578
5559
  createEditorStateStore,
5579
5560
  createEditorStateTransaction,
5580
5561
  createElement,
@@ -5613,7 +5594,7 @@ export {
5613
5594
  mention,
5614
5595
  overlap,
5615
5596
  preventNewline,
5616
- processAction,
5597
+ processEditorPayload,
5617
5598
  removeBlockquote,
5618
5599
  removeCodeblock,
5619
5600
  removeLink,
@@ -5629,6 +5610,8 @@ export {
5629
5610
  setSelection,
5630
5611
  setStyle,
5631
5612
  singleValueFacet,
5613
+ stackItemContentEditorClassNames,
5614
+ stackItemContentToolbarClassNames,
5632
5615
  table,
5633
5616
  tags2 as tags,
5634
5617
  textRange,
@@ -5646,9 +5629,9 @@ export {
5646
5629
  useCommentClickListener,
5647
5630
  useCommentState,
5648
5631
  useComments,
5632
+ useEditorToolbarState,
5649
5633
  useFormattingState,
5650
5634
  useTextEditor,
5651
- useToolbarContext,
5652
5635
  wrapWithCatch
5653
5636
  };
5654
5637
  //# sourceMappingURL=index.mjs.map